From: mjw@wray-m-3.hpl.hp.com Date: Tue, 29 Jun 2004 12:07:26 +0000 (+0000) Subject: bitkeeper revision 1.1023.1.6 (40e15b7edePZdBO_2yFHsmAtSxfw9g) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~18092^2~5^2 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=92d34c41187747622018e15c70c4b01f388a044e;p=xen.git bitkeeper revision 1.1023.1.6 (40e15b7edePZdBO_2yFHsmAtSxfw9g) Change to using the vifctl script to init networking and bring vifs up and down instead of doing it all ourselves. --- diff --git a/.rootkeys b/.rootkeys index c2f8c5d26e..91a12ae1e3 100644 --- a/.rootkeys +++ b/.rootkeys @@ -239,6 +239,7 @@ 40c9c468icGyC5RAF1bRKsCXPDCvsA tools/xen/Makefile 40dc4076hGpwa8-sWRN0jtXZeQJuKg tools/xen/lib/__init__.py 40dfd40aMOhnw_cQLve9462UR5yYxQ tools/xen/lib/ext/__init__.py +40d8915cyoVA0hJxiBFNymL7YvDaRg tools/xen/lib/util/Brctl.py 40dfd40aGqGkiopOOgJxSF4iCbHM0Q tools/xen/lib/util/__init__.py 4055ee4dwy4l0MghZosxoiu6zmhc9Q tools/xen/lib/util/console_client.py 40c9c468IienauFHQ_xJIcqnPJ8giQ tools/xen/lib/util/ip.py @@ -247,7 +248,7 @@ 40c9c468Um_qc66OQeLEceIz1pgD5g tools/xen/lib/xend/EventServer.py 40c9c468U8EVl0d3G--8YXVg6VJD3g tools/xen/lib/xend/EventTypes.py 40c9c468QJTEuk9g4qHxGpmIi70PEQ tools/xen/lib/xend/PrettyPrint.py -40d8915cyoVA0hJxiBFNymL7YvDaRg tools/xen/lib/xend/XendBridge.py +40e15b7eeQxWE_hUPB2YTgM9fsZ1PQ tools/xen/lib/xend/Vifctl.py 40c9c4688m3eqnC8fhLu1APm36VOVA tools/xen/lib/xend/XendClient.py 40c9c468t6iIKTjwuYoe-UMCikDcOQ tools/xen/lib/xend/XendConsole.py 40c9c468WnXs6eOUSff23IIGI4kMfQ tools/xen/lib/xend/XendDB.py @@ -291,6 +292,7 @@ 40cf2937Z8WCNOnO2FcWdubvEAF9QQ tools/xen/lib/xm/shutdown.py 40c9c469kT0H9COWzA4XzPBjWK0WsA tools/xen/netfix 40c9c469n2RRwCmjWdjdyyVRWKmgWg tools/xen/setup.py +40e15b7edWEtBf_oe3eBwGKuh1dyzQ tools/xen/vifctl 40c9c4697z76HDfkCLdMhmaEwzFoNQ tools/xen/xend 40cf2937dqM1jWW87O5OoOYND8leuA tools/xen/xm 40431ac64Hj4ixUnKmlugZKhXPFE_Q tools/xend-old/Makefile diff --git a/tools/xen/Makefile b/tools/xen/Makefile index 642cd2273e..8732a30932 100644 --- a/tools/xen/Makefile +++ b/tools/xen/Makefile @@ -14,6 +14,8 @@ install: all install -m0755 xend $(prefix)/usr/sbin install -m0755 netfix $(prefix)/usr/sbin install -m0755 xm $(prefix)/usr/sbin + mkdir -p $(prefix)/etc/xen/xend + install -m0755 vifctl $(prefix)/etc/xen/xend clean: rm -rf build *.pyc *.pyo *.o *.a *~ diff --git a/tools/xen/lib/util/Brctl.py b/tools/xen/lib/util/Brctl.py new file mode 100644 index 0000000000..32dd16bf81 --- /dev/null +++ b/tools/xen/lib/util/Brctl.py @@ -0,0 +1,161 @@ +"""Bridge control utilities. +""" +import os +import os.path +import re +import sys + +os.defpath = os.defpath + ':/sbin:/usr/sbin:/usr/local/sbin' +CMD_IFCONFIG = 'ifconfig' +CMD_ROUTE = 'route' +CMD_BRCTL = 'brctl' +CMD_IPTABLES = "iptables" + +opts = None + +class Opts: + + def __init__(self, defaults): + for (k, v) in defaults.items(): + setattr(self, k, v) + pass + +def cmd(p, s): + """Print and execute command 'p' with args 's'. + """ + global opts + c = p + ' ' + s + if opts.verbose: print c + if not opts.dryrun: + os.system(c) + +def vif_bridge_add(params): + """Add the network interface for vif on dom to a bridge. + """ + cmd(CMD_BRCTL, 'addif %(bridge)s %(vif)s' % params) + return bridge + +def vif_bridge_rem(params): + """Remove the network interface for vif on dom from a bridge. + """ + cmd(CMD_BRCTL, 'delif %(bridge)s %(vif)s' % params) + +def vif_restrict_addr(vif, addr, delete=0): + d = { 'vif': vif, 'addr': addr} + if delete: + d['flag'] = '-D' + else: + d['flag'] = '-A' + cmd(CMD_IPTABLES, '-P FORWARD DROP') + cmd(CMD_IPTABLES, '%(flag)s FORWARD -m physdev --physdev-in %(vif)s -s %(addr)s -j ACCEPT' % d) + cmd(CMD_IPTABLES, '%(flag)s FORWARD -m physdev --physdev-out %(vif)s -d %(addr)s -j ACCEPT' % d) + +def bridge_create(bridge, **kwd): + """Create a bridge. + Defaults hello time to 0, forward delay to 0 and stp off. + """ + cmd(CMD_BRCTL, 'addbr %s' % bridge) + if kwd.get('hello', None) is None: + kwd['hello'] = 0 + if kwd.get('fd', None) is None: + kwd['fd'] = 0 + if kwd.get('stp', None) is None: + kwd['stp'] = 'off' + bridge_set(bridge, **kwd) + +def bridge_set(bridge, hello=None, fd=None, stp=None): + """Set bridge parameters. + """ + if hello is not None: + cmd(CMD_BRCTL, 'sethello %s %d' % (bridge, hello)) + if fd is not None: + cmd(CMD_BRCTL, 'setfd %s %d' % (bridge, fd)) + if stp is not None: + cmd(CMD_BRCTL, 'stp %s %s' % (bridge, stp)) + +def bridge_del(bridge): + """Delete a bridge. + """ + cmd(CMD_BRCTL, 'delbr %s' % bridge) + +def routes(): + """Return a list of the routes. + """ + fin = os.popen(CMD_ROUTE + ' -n', 'r') + routes = [] + for x in fin: + if x.startswith('Kernel'): continue + if x.startswith('Destination'): continue + x = x.strip() + y = x.split() + z = { 'destination': y[0], + 'gateway' : y[1], + 'mask' : y[2], + 'flags' : y[3], + 'metric' : y[4], + 'ref' : y[5], + 'use' : y[6], + 'interface' : y[7] } + routes.append(z) + return routes + +def ifconfig(interface): + """Return the ip config for an interface, + """ + fin = os.popen(CMD_IFCONFIG + ' %s' % interface, 'r') + inetre = re.compile('\s*inet\s*addr:(?P
\S*)\s*Bcast:(?P\S*)\s*Mask:(?P\S*)') + info = None + for x in fin: + m = inetre.match(x) + if not m: continue + info = m.groupdict() + info['interface'] = interface + break + return info + +def reconfigure(interface, bridge): + """Reconfigure an interface to be attached to a bridge, and give the bridge + the IP address etc. from interface. Move the default route to the interface + to the bridge. + + """ + global opts + intf_info = ifconfig(interface) + if not intf_info: + print 'Interface not found:', interface + return + #bridge_info = ifconfig(bridge) + #if not bridge_info: + # print 'Bridge not found:', bridge + # return + route_info = routes() + intf_info['bridge'] = bridge + intf_info['gateway'] = None + for r in route_info: + if (r['destination'] == '0.0.0.0' and + 'G' in r['flags'] and + r['interface'] == interface): + intf_info['gateway'] = r['gateway'] + if not intf_info['gateway']: + print 'Gateway not found: ', interface + return + cmd(CMD_IFCONFIG, + '%(bridge)s %(address)s netmask %(mask)s broadcast %(broadcast)s up' + % intf_info) + cmd(CMD_ROUTE, + 'add default gateway %(gateway)s dev %(bridge)s' + % intf_info) + cmd(CMD_BRCTL, 'addif %(bridge)s %(interface)s' % intf_info) + cmd(CMD_IFCONFIG, '%(interface)s 0.0.0.0' % intf_info) + +defaults = { + 'verbose' : 1, + 'dryrun' : 0, + } + +opts = Opts(defaults) + +def set_opts(val): + global opts + opts = val + return opts diff --git a/tools/xen/lib/xend/Vifctl.py b/tools/xen/lib/xend/Vifctl.py new file mode 100644 index 0000000000..49df8f6bd0 --- /dev/null +++ b/tools/xen/lib/xend/Vifctl.py @@ -0,0 +1,28 @@ +import os +import os.path +import sys + +VIFCTL = '/etc/xen/xend/vifctl' + +def init(): + os.system(VIFCTL + ' init ') + +def up(vif, mac=None, bridge=None, ipaddr=[]): + args = ['vif=%s' % vif] + if mac: + args.append('mac=%s' % mac) + if bridge: + args.append('bridge=%s' % bridge) + if ipaddr: + args.append('ipaddr=%s' % ','.join(ipaddr)) + os.system(VIFCTL + ' up ' + ' '.join(args)) + +def down(vif, mac=None, bridge=None, ipaddr=[]): + args = ['vif=%s' % vif] + if mac: + args.append('mac=%s' % mac) + if bridge: + args.append('bridge=%s' % bridge) + if ipaddr: + args.append('ipaddr=%s' % ','.join(ipaddr)) + os.system(VIFCTL + ' down ' + ' '.join(args)) diff --git a/tools/xen/lib/xend/XendBridge.py b/tools/xen/lib/xend/XendBridge.py deleted file mode 100644 index f1584552de..0000000000 --- a/tools/xen/lib/xend/XendBridge.py +++ /dev/null @@ -1,193 +0,0 @@ -"""Bridge control utilities. -""" -import os -import os.path -import re -import sys - -from xen.xend import XendRoot -xroot = XendRoot.instance() - -os.defpath = os.defpath + ':/sbin:/usr/sbin:/usr/local/sbin' -CMD_IFCONFIG = 'ifconfig' -CMD_ROUTE = 'route' -CMD_BRCTL = 'brctl' -CMD_IPTABLES = "iptables" - -DEFAULT_BRIDGE = 'nbe-br' -DEFAULT_INTERFACE = 'eth0' - -opts = None - -class Opts: - - def __init__(self, defaults): - for (k, v) in defaults.items(): - setattr(self, k, v) - pass - -def cmd(p, s): - """Print and execute command 'p' with args 's'. - """ - global opts - c = p + ' ' + s - if opts.verbose: print c - if not opts.dryrun: - os.system(c) - -def default_bridge(): - return xroot.get_config_value('bridge', DEFAULT_BRIDGE) - -def default_interface(): - return xroot.get_config_value('interface', DEFAULT_INTERFACE) - -def vif_dev(dom, vif): - """Return the name of the network interface for vif on domain dom. - """ - return "vif%d.%d" % (dom, vif) - -def vif_bridge_add(dom, vif, bridge=None): - """Add the network interface for vif on dom to a bridge. - """ - if not bridge: bridge = default_bridge() - d = { 'bridge': bridge, 'vif': vif_dev(dom, vif) } - cmd(CMD_BRCTL, 'addif %(bridge)s %(vif)s' % d) - return bridge - -def vif_bridge_rem(dom, vif, bridge=None): - """Remove the network interface for vif on dom from a bridge. - """ - if not bridge: bridge = default_bridge() - print 'vif_bridge_rem>', dom, vif, bridge - d = { 'bridge': bridge, 'vif': vif_dev(dom, vif) } - cmd(CMD_BRCTL, 'delif %(bridge)s %(vif)s' % d) - -def vif_restrict_addr(dom, vif, addr, delete=0): - d = { 'vif': vif_dev(dom, vif), 'addr': addr} - if delete: - d['flag'] = '-D' - else: - d['flag'] = '-A' - cmd(CMD_IPTABLES, '-P FORWARD DROP') - cmd(CMD_IPTABLES, '%(flag)s FORWARD -m physdev --physdev-in %(vif)s -s %(addr)s -j ACCEPT' % d) - cmd(CMD_IPTABLES, '%(flag)s FORWARD -m physdev --physdev-out %(vif)s -d %(addr)s -j ACCEPT' % d) - -def bridge_create(bridge=None, **kwd): - """Create a bridge. - Defaults hello time to 0, forward delay to 0 and stp off. - """ - if not bridge: bridge = default_bridge() - cmd(CMD_BRCTL, 'addbr %s' % bridge) - if kwd.get('hello', None) is None: - kwd['hello'] = 0 - if kwd.get('fd', None) is None: - kwd['fd'] = 0 - if kwd.get('stp', None) is None: - kwd['stp'] = 'off' - bridge_set(bridge, **kwd) - -def bridge_set(bridge, hello=None, fd=None, stp=None): - """Set bridge parameters. - """ - if hello is not None: - cmd(CMD_BRCTL, 'sethello %s %d' % (bridge, hello)) - if fd is not None: - cmd(CMD_BRCTL, 'setfd %s %d' % (bridge, fd)) - if stp is not None: - cmd(CMD_BRCTL, 'stp %s %s' % (bridge, stp)) - -def bridge_del(bridge=None): - """Delete a bridge. - """ - if not bridge: bridge = default_bridge() - cmd(CMD_BRCTL, 'delbr %s' % bridge) - -def routes(): - """Return a list of the routes. - """ - fin = os.popen(CMD_ROUTE + ' -n', 'r') - routes = [] - for x in fin: - if x.startswith('Kernel'): continue - if x.startswith('Destination'): continue - x = x.strip() - y = x.split() - z = { 'destination': y[0], - 'gateway' : y[1], - 'mask' : y[2], - 'flags' : y[3], - 'metric' : y[4], - 'ref' : y[5], - 'use' : y[6], - 'interface' : y[7] } - routes.append(z) - return routes - -def ifconfig(interface): - """Return the ip config for an interface, - """ - fin = os.popen(CMD_IFCONFIG + ' %s' % interface, 'r') - inetre = re.compile('\s*inet\s*addr:(?P
\S*)\s*Bcast:(?P\S*)\s*Mask:(?P\S*)') - info = None - for x in fin: - m = inetre.match(x) - if not m: continue - info = m.groupdict() - info['interface'] = interface - break - return info - -def reconfigure(interface=None, bridge=None): - """Reconfigure an interface to be attached to a bridge, and give the bridge - the IP address etc. from interface. Move the default route to the interface - to the bridge. - - If opts.create is true, creates the bridge. - """ - global opts - if not interface: interface = default_interface() - if not bridge: bridge = default_bridge() - intf_info = ifconfig(interface) - if not intf_info: - print 'Interface not found:', interface - return - if opts.create: - bridge_create(bridge) - #bridge_info = ifconfig(bridge) - #if not bridge_info: - # print 'Bridge not found:', bridge - # return - route_info = routes() - intf_info['bridge'] = bridge - intf_info['gateway'] = None - for r in route_info: - if (r['destination'] == '0.0.0.0' and - 'G' in r['flags'] and - r['interface'] == interface): - intf_info['gateway'] = r['gateway'] - if not intf_info['gateway']: - print 'Gateway not found: ', interface - return - cmd(CMD_IFCONFIG, - '%(bridge)s %(address)s netmask %(mask)s broadcast %(broadcast)s up' - % intf_info) - cmd(CMD_ROUTE, - 'add default gateway %(gateway)s dev %(bridge)s' - % intf_info) - cmd(CMD_BRCTL, 'addif %(bridge)s %(interface)s' % intf_info) - cmd(CMD_IFCONFIG, '%(interface)s 0.0.0.0' % intf_info) - -defaults = { - 'interface': default_interface(), - 'bridge' : default_bridge(), - 'verbose' : 1, - 'dryrun' : 0, - 'create' : 0, - } - -opts = Opts(defaults) - -def set_opts(val): - global opts - opts = val - return opts diff --git a/tools/xen/lib/xend/XendDomainInfo.py b/tools/xen/lib/xend/XendDomainInfo.py index c17109c85a..50fcf26fe2 100644 --- a/tools/xen/lib/xend/XendDomainInfo.py +++ b/tools/xen/lib/xend/XendDomainInfo.py @@ -24,8 +24,6 @@ import sxp import XendConsole xendConsole = XendConsole.instance() -import XendBridge - import server.SrvDaemon xend = server.SrvDaemon.instance() @@ -765,7 +763,7 @@ def vm_dev_vif(vm, val, index): if devid: dev.setprop('id', devid) bridge = sxp.child_value(val, "bridge") - dev.bridge_add(bridge) + dev.up(bridge) vm.add_device('vif', dev) print 'vm_dev_vif> created', dev return id diff --git a/tools/xen/lib/xend/server/SrvServer.py b/tools/xen/lib/xend/server/SrvServer.py index 6535ad3f37..ac201dd10d 100644 --- a/tools/xen/lib/xend/server/SrvServer.py +++ b/tools/xen/lib/xend/server/SrvServer.py @@ -32,7 +32,7 @@ from twisted.internet import reactor from xen.xend import XendRoot xroot = XendRoot.instance() -from xen.xend import XendBridge +from xen.xend import Vifctl from SrvRoot import SrvRoot @@ -48,8 +48,7 @@ def create(port=None, interface=None, bridge=0): reactor.listenTCP(port, site, interface=interface) def init_bridge(): - XendBridge.bridge_create() - XendBridge.reconfigure() + Vifctl.init() def main(port=None, interface=None): create(port, interface) diff --git a/tools/xen/lib/xend/server/netif.py b/tools/xen/lib/xend/server/netif.py index 01391f7b5f..2b01805be6 100755 --- a/tools/xen/lib/xend/server/netif.py +++ b/tools/xen/lib/xend/server/netif.py @@ -4,7 +4,7 @@ from twisted.internet import defer from xen.xend import sxp from xen.xend import PrettyPrint -from xen.xend import XendBridge +from xen.xend import Vifctl import channel import controller @@ -115,10 +115,11 @@ class NetDev(controller.Dev): self.mac = mac self.evtchn = None self.bridge = None + self.ipaddr = [] def sxpr(self): vif = str(self.vif) - mac = ':'.join(map(lambda x: "%x" % x, self.mac)) + mac = self.get_mac() val = ['netdev', ['vif', vif], ['mac', mac]] if self.bridge: val.append(['bridge', self.bridge]) @@ -128,20 +129,31 @@ class NetDev(controller.Dev): self.evtchn['port2']]) return val - def bridge_add(self, bridge): - self.bridge = XendBridge.vif_bridge_add(self.controller.dom, self.vif, bridge) + def get_vifname(self): + return "vif%d.%d" % (self.controller.dom, self.vif) - def bridge_rem(self): - if not self.bridge: return - XendBridge.vif_bridge_rem(self.controller.dom, self.vif, self.bridge) - self.bridge = None + def get_mac(self): + return ':'.join(map(lambda x: "%x" % x, self.mac)) + + def vifctl_params(self): + return { 'mac' : self.get_mac(), + 'bridge': self.bridge, + 'ipaddr': self.ipaddr } + + def up(self, bridge=None, ipaddr=[]): + self.bridge = bridge + self.ipaddr = ipaddr + Vifctl.up(self.get_vifname(), **self.vifctl_params()) + + def down(self): + Vifctl.down(self.get_vifname(), **self.vifctl_params()) def destroy(self): def cb_destroy(val): self.controller.send_be_destroy(self.vif) print 'NetDev>destroy>', 'vif=', self.vif PrettyPrint.prettyprint(self.sxpr()) - self.bridge_rem() + self.down() d = self.controller.factory.addDeferred() d.addCallback(cb_destroy) self.controller.send_be_disconnect(self.vif) diff --git a/tools/xen/vifctl b/tools/xen/vifctl new file mode 100644 index 0000000000..095dc987f4 --- /dev/null +++ b/tools/xen/vifctl @@ -0,0 +1,148 @@ +#!/usr/bin/python +# -*- mode: python; -*- +#============================================================================ +# Xen vif control script. +# +# vifctl init [bridge=] [interface=] +# +# Called when xend starts up. Default behaviour is to create +# and add to it, moving its IP address to and adjusting routes. +# +# vifctl (up|down) vif= mac= [bridge=] (ipaddr=)* +# +# Called when a vif is brought up or down. Default behaviour is to add +# the vif to on up and remove it from the bridge on down. +# If ipaddr is specified, iptables rules for the ip addresses are +# added on up and removed on down. The bridge a vif is added to can +# be set in the vm config. +# +# The default bridge is nbe-br. +# The default interface is eth0. +# +#============================================================================ + +import sys +import types + +from xen.util import Brctl + +from xen.xend import XendRoot +xroot = XendRoot.instance() + +class VifControl: + + prefix = 'vifctl_' + + DEFAULT_BRIDGE = 'nbe-br' + DEFAULT_INTERFACE = 'eth0' + + def __init__(self): + self.name = 'vifctl' + + def main(self, args): + if len(args) < 2: + usage(args) + self.name = args[0] + cmd = self.prefix + args[1] + meth = getattr(self, cmd, self.unknown) + meth(args[1:]) + + def usage(self, args, out=sys.stderr): + print >>out, 'Missing command, try \n%s help' % self.name + + def unknown(self, args, out=sys.stderr): + print >>out, 'Unknown command:', args[1] + self.help(out=out) + sys.exit(1) + + def help(self, out=sys.stdout): + print >>out, 'Commands are:', + for x in vars(self): + if x.startswith(prefix): + cmd = x[len(prefix):] + print >>out, cmd, + print >>out + + def getparams(self, d, args, req=[]): + """Parse args of the form 'key=val'. Valid keys are the ones + in the dict 'd' passed in. If entries in 'd' have list values the + values of the keys are appended. + + If 'req' is specified it is a list of required keys. + """ + for x in args: + (k, v) = x.split('=') + k = k.strip() + v = v.strip() + if k not in d: + print >>sys.stderr, 'Invalid parameter: ', k + sys.exit(1) + vold = d[k] + if isinstance(vold , types.ListType): + d[k] = vold + v + else: + d[k] = v + for x in req: + if not d[x]: + print >>sys.stderr, 'Missing parameter:', x + sys.exit(1) + return d + + def vifctl_help(self, args): + self.help() + + def default_bridge(self): + return xroot.get_config_value('bridge', self.DEFAULT_BRIDGE) + + def default_interface(self): + return xroot.get_config_value('interface', self.DEFAULT_INTERFACE) + + def vifctl_init(self, args): + """Entry point for 'vifctl init'. + """ + d = { 'bridge' : self.default_bridge(), + 'interface': self.default_interface() } + params = self.getparams(d, args[1:]) + interface = params['interface'] + bridge = params['bridge'] + # Create bridge 'bridge'. + Brctl.bridge_create(bridge) + # Reconfigure so that 'interface' is added to 'bridge', + # and 'bridge' has the IP address from 'interface'. + Brctl.reconfigure(interface, bridge) + + def vifparams(self, args): + d = { 'vif' : None, + 'mac' : None, + 'bridge': self.default_bridge(), + 'ipaddr': [] } + d = self.getparams(d, args, req=['vif', 'mac']) + return d + + def vifctl_up(self, args): + """Entry point for 'vifctl up'. + """ + params = self.vifparams(args[1:]) + # Add the vif to its bridge. + Brctl.vif_bridge_add(params) + if params['ipaddr']: + # Add iptables rules for the ip addresses. + vif = params['vif'] + for ipaddr in params['ipaddr']: + Brctl.vif_restrict_addr(vif, ipaddr) + + def vifctl_down(self, args): + """Entry point for 'vifctl down'. + """ + params = self.vifparams(args[1:]) + # Remove the vif from its bridge. + Brctl.vif_bridge_rem(params) + if params['ip']: + # Remove iptables rules for the ip addresses. + vif = params['vif'] + for ip in params['ip']: + Brctl.vif_restrict_addr(vif, ip, delete=1) + + +if __name__ == "__main__": + VifControl().main(sys.argv)